"""
传输层抽象接口模块
定义USB转CAN通信的抽象接口，为后续具体实现预留
"""
from abc import ABC, abstractmethod
from typing import Tuple, Optional, List
from dataclasses import dataclass

from app.dev_com.dev_com import Dev_UsbToCan

@dataclass
class TransCanFrame:
    """Tranport CAN数据帧结构"""
    can_id: int           # CAN ID
    data: list[int]          # 数据域
    is_extended: bool    # 是否扩展帧
    

class ITransport(ABC):
    """传输层抽象接口"""
    
    @abstractmethod
    def open(self, baudrate: int, channel: int = 0) -> Tuple[bool, str]:
        """
        初始化传输层
        
        Args:
            baudrate: 波特率
            channel: 通道号
            
        Returns:
            Tuple[bool, str]: (是否成功, 消息)
        """
        pass
    
    @abstractmethod
    def close(self) -> Tuple[bool, str]:
        """
        反初始化传输层
        
        Returns:
            Tuple[bool, str]: (是否成功, 消息)
        """
        pass
    
    @abstractmethod
    def send_frame(self, frame: TransCanFrame) -> Tuple[bool, str]:
        """
        发送CAN帧
        
        Args:
            frame: CAN数据帧
            
        Returns:
            Tuple[bool, str]: (是否成功, 消息)
        """
        pass
    
    @abstractmethod
    def recv_frame(self, timeout_ms: int = 1) -> Tuple[bool, Optional[TransCanFrame], str]:
        """
        接收CAN帧
        
        Args:
            timeout_ms: 超时时间(毫秒)
            
        Returns:
            Tuple[bool, Optional[CanFrame], str]: (是否成功, CAN帧数据, 消息)
        """
        pass
    
    @abstractmethod
    def is_connected(self) -> bool:
        """
        检查连接状态
        
        Returns:
            bool: 是否已连接
        """
        pass


class MockTransport(ITransport):
    """
    模拟传输层实现
    用于测试和开发阶段，实际USB转CAN模块可替换此实现
    """
    
    def __init__(self):
        self._connected = False
        self._tx_id = 0x001
        self._rx_id = 0x000
        
    def open(self, baudrate: int, channel: int = 0) -> Tuple[bool, str]:
        """初始化模拟传输层"""
        try:
            # 模拟初始化过程
            self._connected = True
            return True, f"模拟传输层初始化成功 - 波特率:{baudrate}, 通道:{channel}"
        except Exception as e:
            return False, f"模拟传输层初始化失败: {str(e)}"
    
    def close(self) -> Tuple[bool, str]:
        """反初始化模拟传输层"""
        try:
            self._connected = False
            return True, "模拟传输层反初始化成功"
        except Exception as e:
            return False, f"模拟传输层反初始化失败: {str(e)}"
    
    def send_frame(self, frame: TransCanFrame) -> Tuple[bool, str]:
        """发送CAN帧 - 模拟实现"""
        if not self._connected:
            return False, "传输层未连接"
        
        try:
            # 模拟发送过程
            print(f"[模拟发送] CAN ID: 0x{frame.can_id:03X}, 数据: {frame.data.hex().upper()}")
            return True, "发送成功"
        except Exception as e:
            return False, f"发送失败: {str(e)}"
    
    def recv_frame(self, timeout_ms: int = 1000) -> Tuple[bool, Optional[TransCanFrame], str]:
        """接收CAN帧 - 模拟实现"""
        if not self._connected:
            return False, None, "传输层未连接"
        
        try:
            # 模拟接收过程 - 返回XCP连接响应
            mock_rsp = TransCanFrame(
                can_id=self._rx_id,
                data=bytes([0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
                is_extended=False
            )
            print(f"[模拟接收] CAN ID: 0x{mock_rsp.can_id:03X}, 数据: {mock_rsp.data.hex().upper()}")
            return True, mock_rsp, "接收成功"
        except Exception as e:
            return False, None, f"接收失败: {str(e)}"
    
    def is_connected(self) -> bool:
        """检查连接状态"""
        return self._connected
    
    def set_can_ids(self, tx_id: int, rx_id: int) -> None:
        """设置CAN ID"""
        self._tx_id = tx_id
        self._rx_id = rx_id


class UsbCanTransport(ITransport):
    """
    USB转CAN传输层实现
    此处为接口预留，具体实现需要根据实际的USB转CAN模块API来完成
    """
    
    def __init__(self, name: str = "usbcan"):
        self._name = name
        self._connected = False
        self._device_handle = None
        
    def open(self, baudrate: int, channel: int = 0) -> Tuple[bool, str]:
        """初始化USB转CAN设备"""
        # TODO: 实现具体的USB转CAN初始化逻辑
        self._device_handle = Dev_UsbToCan(self._name)
        suc, msg = self._device_handle.open()
        if not suc:
            return suc, msg
        self._connected = True
        return True, "OK"
        # 示例代码框架：
        # try:
        #     # 1. 打开USB设备
        #     self._device_handle = usb_can_open(channel)
        #     
        #     # 2. 配置波特率
        #     usb_can_set_baudrate(self._device_handle, baudrate)
        #     
        #     # 3. 启动CAN控制器
        #     usb_can_start(self._device_handle)
        #     
        #     self._connected = True
        #     return True, "USB转CAN初始化成功"
        # except Exception as e:
        #     return False, f"USB转CAN初始化失败: {str(e)}"
        
        # return True, "OK"
    
    def close(self) -> Tuple[bool, str]:
        """反初始化USB转CAN设备"""
        self._device_handle.close()
        self._connected = False
        return True, "OK"
    
    def send_frame(self, frame: TransCanFrame) -> Tuple[bool, str]:
        """发送CAN帧"""
        if not self._connected:
            return False, "USB转CAN未连接"
        suc, msg = self._device_handle.send_can_msg(frame.can_id, frame.data, frame.is_extended)
        return suc, msg
    
    def recv_frame(self, timeout_ms: int = 1) -> Tuple[bool, Optional[TransCanFrame], str]:
        """接收CAN帧"""
        # TODO: 实现具体的CAN帧接收逻辑
        if not self._connected:
            return False, None, "USB转CAN未连接"
        suc, frame, msg = self._device_handle.recv_can_frame(timeout_ms)
        if not suc:
            return suc, None, msg
        return True, frame, "OK"    
    
    def is_connected(self) -> bool:
        """检查连接状态"""
        return self._connected 